package xfuzzy.alg_genetico.indeterminado.cross;

import java.util.Random;
import java.util.UUID;

import xfuzzy.xfghl.codification.DoubleChromosome;
import xfuzzy.xfghl.codification.EncodingSymbols;

public class CruceOrdenConControl implements EncodingSymbols {
	
	public CruceOrdenConControl(long seed)  {
		
		//super(seed);
	}

	public DoubleChromosome cruzar(DoubleChromosome padre1, DoubleChromosome padre2) {
		
		DoubleChromosome hijo = new DoubleChromosome(padre1.getNumVariables());
		//this.cruzarVariables(padre1, padre2, hijo);
		this.cruzarEstructura(padre1, padre2, hijo);
		return hijo;
	}

	protected DoubleChromosome cruzarEstructura(DoubleChromosome padre1, DoubleChromosome padre2, DoubleChromosome hijo) {

		int longitud_estructura = padre1.getNumVariables() + padre2.getNumModulos();
		char [] estructura_c1 = padre1.getEstructura();
		char [] estructura_c2 = padre2.getEstructura();
		char [] estructura_hijo = new char[longitud_estructura];
		Random rnd = new Random(UUID.randomUUID().hashCode());
		int modulos = 0, variables = 0;
		int indice1 = rnd.nextInt(longitud_estructura);
		int indice2 = rnd.nextInt(longitud_estructura);
		while (indice1 == indice2)
			indice2 = rnd.nextInt(longitud_estructura);
		
		int indice_superior = 0, indice_inferior = 0;
		if (indice1 > indice2)  {
			indice_superior = indice1;
			indice_inferior = indice2;
		}
		else  {
			indice_superior = indice2;
			indice_inferior = indice1;
		}
		
		// Copia el intervalo [indice1, indice2] desde el cromosoma c1 al cromosoma hijo
		for (int indice_cruce = indice_inferior; indice_cruce <= indice_superior; indice_cruce++)  {
			 if (estructura_c1[indice_cruce] == moduleSymbol) 
				 modulos++;
			 if (estructura_c1[indice_cruce] == variableSymbol)
				 variables++;
			estructura_hijo[indice_cruce] = estructura_c1[indice_cruce];
		}
		
		// Copia el resto del cromosoma hijo desde el cromosoma c2 comprobando que el indice del bucle for no este en el 
		// intervalo [indice1, indice2] y que no se supere el numero de modulos ni de variables
		for (int indice = 0; indice < longitud_estructura; indice++)  {
			 // se comprueba que no este en el intervalo [indice1, indice2]
			 if ((indice < indice_inferior) || (indice > indice_superior))  {
				 if (estructura_c2[indice] == moduleSymbol)  {
					 if (modulos < padre2.getNumModulos())  {
						 modulos++;
						 estructura_hijo[indice] = estructura_c2[indice];
					 }
					 else  {
						 variables++;
						 estructura_hijo[indice] = variableSymbol;
					 }
				 }
				 if (estructura_c2[indice] == variableSymbol)  {
					 if (variables < padre2.getNumVariables())  {
						 variables++;
						 estructura_hijo[indice] = estructura_c2[indice];
					 }
					 else  {
						 modulos++;
						 estructura_hijo[indice] = moduleSymbol;
					 }
				 }
			 }
		}
		
		hijo.setEstructura(estructura_hijo);
		
		System.out.println("Indice 1 = " + indice1);
		System.out.println("Indice 2 = " + indice2);
		System.out.print("Estructura c1 =   ");
		for (int i = 0; i < estructura_c1.length; i++)
			 System.out.print(estructura_c1[i]);
		System.out.println();
		System.out.print("Estructura c2 =   ");
		for (int i = 0; i < estructura_c2.length; i++)
			 System.out.print(estructura_c2[i]);
		System.out.println();
		System.out.print("Estructura hijo = ");
		for (int i = 0; i < estructura_hijo.length; i++)
			 System.out.print(estructura_hijo[i]);
		System.out.println();
		return hijo;
	}
}
